package com.pubinfo.passbook.shiro.realm;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.pubinfo.passbook.common.exception.ServiceException;
import com.pubinfo.passbook.common.entity.TSystemUser;
import com.pubinfo.passbook.common.service.master.TSystemUserService;
import com.pubinfo.passbook.shiro.token.JwtUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Slf4j
@Service
public class CustomRealm extends AuthorizingRealm {
  @Autowired
  TSystemUserService userService;
  
  /**
   * 设置凭证匹配器,告诉认证管理器使用什么
   * 加密算法对用户输入的密码进行加密操作
   */
  @Override
  public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) {
    //构建凭证匹配对象
    HashedCredentialsMatcher cMatcher =
        new HashedCredentialsMatcher();
    //设置加密算法
    cMatcher.setHashAlgorithmName("MD5");
    //设置加密次数
    cMatcher.setHashIterations(1);
    super.setCredentialsMatcher(cMatcher);
  }
  
  //授权操作
  @Override
  protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
    SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
    return authorizationInfo;
  }
  
  //
//  //验证操作
//  @Override
//  protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken)
//      throws AuthenticationException {
//    log.info("realm的验证操作");
//    String token1 = (String) authenticationToken.getPrincipal();
//    if (StringUtils.isBlank(token1)) {
//      throw new ServiceException("该用户并不存在");
//    }
//    String token = (String) authenticationToken.getCredentials();
//    // 解密获得username，用于和数据库进行对比
//    String username = JwtUtil.getUserNameFromToken(token);
//    String userId = JwtUtil.getUserIdFromToken(token);
//
//    if (StringUtils.isBlank(username) || StringUtils.isBlank(userId)) {
//      throw new AuthenticationException("该用户并不存在");
//    }
//    if (JwtUtil.BILLING_USER_ID.equals(userId) &&
//        !JwtUtil.verify(token, username, userId, JwtUtil.BILLING_SECRET)) {
//      throw new AuthenticationException("token 已经过期");
//    } else if (!JwtUtil.verify(token, username, userId, JwtUtil.SECRET)) {
//      throw new AuthenticationException("token 已经过期");
//    }
//    UsernamePasswordToken upToken = (UsernamePasswordToken) authenticationToken;
//
//    username = upToken.getUsername();
//    QueryWrapper<TSystemUser> queryWrapper = new QueryWrapper<>();
//    queryWrapper.eq("username", username);
//    List<TSystemUser> userList = userService.list(queryWrapper);
//    TSystemUser user = userList.get(0);
//    if (CollectionUtils.isEmpty(userList)) {
//      throw new ServiceException("该用户并不存在");
//    }
//
//    ByteSource credentialsSalt =
//        ByteSource.Util.bytes(user.getSalt());
//
//    SimpleAuthenticationInfo info =
//        new SimpleAuthenticationInfo(
//            user,//principal 身份 user
//            user.getPassword(),//hashedCredentials 已加密的凭证的信息
//            credentialsSalt,//credentialsSalt 盐值
//            getName());//realmName
//    return info;//返回给调用者(SecurityManager)
//
//  }
//
//验证操作
  @Override
  protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken)
      throws AuthenticationException {
    log.info("realm的验证操作");
    String token = (String) authenticationToken.getPrincipal();
    if (StringUtils.isBlank(token)) {
      throw new ServiceException("该用户并不存在");
    }
    UsernamePasswordToken upToken = (UsernamePasswordToken) authenticationToken;
    
    String username = upToken.getUsername();
    QueryWrapper<TSystemUser> queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("username", username);
    List<TSystemUser> userList = userService.list(queryWrapper);
    TSystemUser user = userList.get(0);
    if (CollectionUtils.isEmpty(userList)) {
      throw new ServiceException("该用户并不存在");
    }
    
    ByteSource credentialsSalt =
        ByteSource.Util.bytes(user.getSalt());
    
    SimpleAuthenticationInfo info =
        new SimpleAuthenticationInfo(
            user,//principal 身份 user
            user.getPassword(),//hashedCredentials 已加密的凭证的信息
            credentialsSalt,//credentialsSalt 盐值
            getName());//realmName
    return info;//返回给调用者(SecurityManager)
    //return new SimpleAuthenticationInfo(token, token, getName());

//        }
  }
}
